#ifndef PROTOCOL_H
#define PROTOCOL_H

#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<QString>

#define REGIST_OK "regist ok"
#define REGIST_FAILED "regist FAILED : name existed"

#define LOGIN_OK "login ok"
#define LOGIN_FAILED "login FAILED : name error or pwd error or relogin"

#define LOGOFF_OK "logoff ok"
#define LOGOFF_FAILED "logOff FAILED"

#define MODIFYINFO_OK "modify info ok"
#define MODIFYINFO_FAILED "modify info FAILED"

#define SEARCH_USER_ONLINE "online"
#define SEARCH_USER_OFFLINE "offline"
#define SEARCH_USER_EMPTY "NO such People"

#define UNKNOW_ERROR "unknow error"
#define EXISTED_FRIEND "friend exist"
#define ADD_FRIEND_OFFLINE "usr offline"
#define ADD_FRIEND_NOEXIST "usr not exist"
#define ADD_FRIEND_OK "Added message has been sent"

#define DEL_FRIEND_OK "delete friend ok"
#define DEL_FRIEND_FAILED "delete friend failed"

#define DIR_NO_EXIST "dir not exist"
#define CREATE_DIR_OK "create dir ok"
#define DIR_NAME_EXIST "dir name exist"

#define PATH_NOT_EXIST "path does not exist"
#define DELETE_DIR_OK "delete dir ok"
#define DELETE_DIR_FAILED "delete dir failed"
#define DELETE_FILE_OK "delete file ok"
#define DELETE_FILE_FAILED "delete file failed"

#define RENAME_OK "rename ok"
#define RENAME_FAILED "rename failed"
#define ENTER_DIR_FAILED "enter dir failed"
#define ENTER_DIR_OK "enter dir ok"

#define UPLOAD_FILE_OK "upload file ok"                  // 上传文件
#define UPLOAD_FILE_FAILED "upload file failed"
#define UPLOAD_FILE_START "start upload file data"
#define OPEN_FILE_FAILED    "open file failed"
#define NON_FILE                "Non file"
#define DOWNLOAD_FILE_START     "start download file data"

#define MOVE_FILE_OK "move file ok"                      // 移动文件
#define MOVE_FILE_FAILED "move file failed"

#define MOVE_DIR_OK "move dir ok"                      // 移动文件夹
#define MOVE_DIR_FAILED "move dir failed"

#define SHARE_FILE_OK "share file ok"                      // 分享文件
#define SHARE_FILE_FAILED "share file failed"
#define SHARE_DIR_OK "share dir ok"                      // 分享文件夹
#define SHARE_DIR_FAILED "share dir failed"

#define RECV_FILE_OK "recv file ok"                      // 接收文件
#define RECV_FILE_FAILED "recv file failed"
#define RECV_DIR_OK "recv dir ok"                      // 接收文件夹
#define RECV_DIR_FAILED "recv dir failed"


#define MAIN_THREAD_TARGET "ThreadID:Main"
#define HANDLE_FILE_THREAD_TARGET "ThreadID:handleFile"

//消息类型
enum ENUM_MSG_TYPE{
    ENUM_MSG_TYPE_MIN=0,

    ENUM_MSG_TYPE_REGIST_REQUEST,       //注册请求1
    ENUM_MSG_TYPE_REGIST_RESPOND,       //注册回复2

    ENUM_MSG_TYPE_LOGIN_REQUEST,       //登录请求3
    ENUM_MSG_TYPE_LOGIN_RESPOND,       //登录回复4

    ENUM_MSG_TYPE_ALL_ONLINE_USRS_REQUEST,       //所有在线用户请求5
    ENUM_MSG_TYPE_ALL_ONLINE_USRS_RESPOND,       //所有在线用户回复6

    ENUM_MSG_TYPE_SEARCH_USR_REQUEST,       //搜索用户请求7
    ENUM_MSG_TYPE_SEARCH_USR_RESPOND,       //搜索用户回复8

    ENUM_MSG_TYPE_ADD_FRIEND_REQUEST,       //添加好友请求9
    ENUM_MSG_TYPE_ADD_FRIEND_RESPOND,       //添加好友回复10

    ENUM_MSG_TYPE_ADD_FRIEND_AGREE,         //同意添加好友11
    ENUM_MSG_TYPE_ADD_FRIEND_DISAGREE,      //不同意添加好友12

    ENUM_MSG_TYPE_FLUSH_FRIEND_REQUEST,         //刷新好友请求13
    ENUM_MSG_TYPE_FLUSH_FRIEND_RESPOND,         //刷新好友回复14

    ENUM_MSG_TYPE_DELETE_FRIEND_REQUEST,        //删除好友请求15
    ENUM_MSG_TYPE_DELETE_FRIEND_RESPOND,        //删除好友回复16

    ENUM_MSG_TYPE_PRIVATE_CHAT_REQUEST,        //私聊请求17
    ENUM_MSG_TYPE_PRIVATE_CHAT_RESPOND,        //私聊回复18

    ENUM_MSG_TYPE_GROUP_CHAT_REQUEST,        //群聊请求19
    ENUM_MSG_TYPE_GROUP_CHAT_RESPOND,        //群聊回复20

    ENUM_MSG_TYPE_CREATE_DIR_REQUEST,        //创建文件夹请求21
    ENUM_MSG_TYPE_CREATE_DIR_RESPOND,        //创建文件夹回复22

    ENUM_MSG_TYPE_FLUSH_DIR_REQUEST,        //刷新文件请求23
    ENUM_MSG_TYPE_FLUSH_DIR_RESPOND,        //刷新文件回复24

    ENUM_MSG_TYPE_DELETE_DIR_FILE_REQUEST,       //删除文件_文件夹请求25
    ENUM_MSG_TYPE_DELETE_DIR_FILE_RESPOND,       //删除文件_文件夹回复26

    ENUM_MSG_TYPE_RENAME_DIR_FILE_REQUEST,       //重命名文件_文件夹请求27
    ENUM_MSG_TYPE_RENAME_DIR_FILE_RESPOND,       //重命名文件_文件夹回复28

    ENUM_MSG_TYPE_ENTER_DIR_REQUEST,       //进入文件夹请求29
    ENUM_MSG_TYPE_ENTER_DIR_RESPOND,       //进入文件夹回复30

    ENUM_MSG_TYPE_UPLOAD_FILE_REQUEST,       //上传文件请求31
    ENUM_MSG_TYPE_UPLOAD_FILE_RESPOND,       //上传文件回复32

    ENUM_MSG_TYPE_DOWNLOAD_FILE_REQUEST,       //下载文件请求33
    ENUM_MSG_TYPE_DOWNLOAD_FILE_RESPOND,       //下载文件回复34

    ENUM_MSG_TYPE_MOVE_FILE_REQUEST,       //移动文件请求35
    ENUM_MSG_TYPE_MOVE_FILE_RESPOND,       //移动文件回复36

    ENUM_MSG_TYPE_USR_OFFLINE_REQUEST,     //用户下线请求37

    ENUM_MSG_TYPE_THREAD_TARGET,            //线程标识38

    ENUM_MSG_TYPE_FLUSH_FRIEND_AND_TABLE_RESPOND,   //39刷新好友列表和表格

    ENUM_MSG_TYPE_LOGOFF_REQUEST,                   //40注销请求
    ENUM_MSG_TYPE_LOGOFF_RESPOND,                   //41注销回复

    ENUM_MSG_TYPE_GET_ONLINE_FRIEND_REQUEST,         //42获取当前在线好友请求
    ENUM_MSG_TYPE_GET_ONLINE_FRIEND_RESPOND,         //43获取当前在线好友回复

    ENUM_MSG_TYPE_SHARE_FILE_REQUEST,                  //44.分享文件请求
    ENUM_MSG_TYPE_SHARE_FILE_RESPOND,                  //45.分享文件回复
    ENUM_MSG_TYPE_RECV_SHARE_FILE_AGREE,               //46.同意接收文件
    ENUM_MSG_TYPE_RECV_SHARE_FILE_DISAGREE,            //47.不同意接收文件
    ENUM_MSG_TYPE_SHARE_FILE_SUCCESS,                 //48.文件/文件夹分享成功提示

    ENUM_MSG_TYPE_USR_ONLINE_NOTICE,                 //49.用户上线通知
    ENUM_MSG_TYPE_USR_OFFLINE_NOTICE,                 //49.用户下线通知

    ENUM_MSG_TYPE_MODIFY_REQUEST,                   //50.修改用户信息请求
    ENUM_MSG_TYPE_MODIFY_RESPOND,                   //51.修改用户信息回复

    ENUM_MSG_TYPE_MAX=0x00ffffff,
};

// 固定部分：文件元信息 + 柔性数组开头
struct FileInfo {
    int nameLen;     // 文件名的字节长度（UTF-8编码长度）
    int fileType;    // 文件类型（0: 文件夹，1: 文件）
    char fileName[]; // 柔性数组，实际大小为 nameLen 字节
};

struct UserInfo {
    QString name;
    int online;
    int isFriend;
};


//协议数据单元
struct PDU{

    unsigned int uiPDULen;      // 协议数据单元总长度（含自身）
    unsigned int uiMsgType;     // 消息类型标识（如登录请求、文件传输等）
    char caData[64];            //附加信息区（存储文件名、用户ID、用户密码等元数据）

    unsigned int uiMsgLen;      //实际消息体长度（不包含PDU头）uiMsgLen 指示 caMsg 数组的实际长度
    char caMsg[];                //实际消息（柔性数组）
};

PDU *mkPDU(unsigned int uiMsgLen); // 创建PDU，uiMsglen是可变的，总大小可有其计算得到

PDU* copyPDU(const PDU* src);

#endif // PROTOCOL_H
